package com.aaron.socket.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.aaron.socket.utils.I18MessageUtils;
import com.aaron.socket.utils.PropertiesUtils;

/**
 * 
 * @类名称：MultiThreadServer
 * @类描述：
 * @创建人：aaron
 * @修改人：
 * @修改时间：2014年5月11日 下午2:17:10
 * @修改备注：
 * @version:
 */
public class MultiThreadServer
{

    /**
     * 定义日志类
     */
    private final static Logger logger = Logger.getLogger(MultiThreadServer.class
            .getName());

    /**
     * sokcet占用端口
     */
    private int port;

    /**
     * socket服务端对象
     */
    private ServerSocket socketServer;

    /**
     * 线程池对象
     */
    private ExecutorService executorService;

    /**
     * 初始化线程池大小
     */
    private int pool_size;

    public MultiThreadServer() throws IOException
    {
        logger.log(Level.INFO, getMessage("utils.message.log.startInitServerData"));
        // 读取属性文件
        port = Integer.parseInt(readProperty("port"));
        pool_size = Integer.parseInt(readProperty("pool_size"));
        // 实例化
        socketServer = new ServerSocket(port);
        // 初始化线程池
        executorService = Executors.newFixedThreadPool(Runtime.getRuntime()
                .availableProcessors() * pool_size);
        logger.log(Level.INFO, getMessage("utils.message.log.startServer"));

    }

    public void service()
    {
        while (true)
        {
            Socket socket = null;
            try
            {
                socket = socketServer.accept();
                executorService.execute(new Handler(socket));
            } catch (IOException e)
            {
                // TODO Auto-generated catch block
                logger.log(Level.SEVERE,
                        getMessage("utils.message.log.ioException"), e);
            }
        }
    }

    /**
     * 
     * @方法描述：
     * @方法名：readProperty
     * @参数：@param key
     * @返回：void
     * @exception
     * @since
     */
    private static String readProperty(String key)
    {
        return PropertiesUtils.getInstance().readProperty(key);
    }

    /**
     * 
     * @方法描述：
     * @方法名：getMessage
     * @参数：@param key
     * @参数：@return
     * @返回：String
     * @exception
     * @since
     */
    private static String getMessage(String key)
    {
        return I18MessageUtils.getInstance().getMessage(key);
    }

    /**
     * 
     * @类名称：Handler
     * @类描述：
     * @创建人：aaron
     * @修改人：
     * @修改时间：2014年5月11日 下午2:42:10
     * @修改备注：
     * @version:
     */
    class Handler implements Runnable
    {

        private Socket socket = null;

        private Handler(Socket socket)
        {
            this.socket = socket;
        }

        /**
         * 
         * @方法描述：
         * @方法名：getWriter
         * @参数：@param socket
         * @参数：@return
         * @参数：@throws IOException
         * @返回：PrintWriter
         * @exception
         * @since
         */
        private PrintWriter getWriter(Socket socket) throws IOException
        {
            OutputStream socketOut = socket.getOutputStream();
            return new PrintWriter(socketOut, true);
        }

        private BufferedReader getReader(Socket socket) throws IOException
        {

            InputStream socketIn = socket.getInputStream();
            return new BufferedReader(new InputStreamReader(socketIn));
        }

        public void printInfo(String msg)
        {
            logger.log(Level.INFO, "MSG：" + msg);
        }

        @Override
        public void run()
        {
            // TODO Auto-generated method stub

            try
            {
                logger.log(
                        Level.INFO,
                        getMessage("utils.message.log.newSocketConntion")
                                + socket.getInetAddress() + ":"
                                + socket.getPort());
                BufferedReader br = this.getReader(socket);
                PrintWriter pw = this.getWriter(socket);

                String msg = null;
                while (null != (msg = br.readLine()))
                {
                    this.printInfo(msg);
                    pw.println(msg);
                    if ("bye".equals(msg))
                    {
                        logger.log(Level.INFO,
                                getMessage("utils.message.log.endMessage"));
                        break;
                    }
                }
            } catch (IOException e)
            {

                logger.log(Level.SEVERE,
                        getMessage("utils.message.log.ioException"), e);
            } finally
            {
                try
                {
                    if (null != socket)
                    {
                        socket.close();
                    }
                } catch (IOException e)
                {
                    logger.log(Level.SEVERE,
                            getMessage("utils.message.log.ioException"), e);
                }
            }
        }
    }
}
